#include "SocketIO.h"
#include "SearchEngineServer.h"
#include <algorithm>
#include <asm-generic/errno-base.h>
#include <cstddef>
#include <cstring>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;
using std::string;


SocketIO::SocketIO(int fd)
: _fd(fd){}



SocketIO::~SocketIO(){
    close(_fd);
}



// 先读取发送过来的 json 长度
int SocketIO::readMsg(char *buf){
    int jsonLen = 0;
    int ret = 0;
    // 先读序列化数据长度
    ret = read(_fd, &jsonLen, sizeof(int));
    if(-1 == ret && errno == EINTR){
        // errno == EINTR 表示错误类型为中断
        // 中断可以不进行异常处理
    }
    else if(-1 == ret){
        perror("readMsgLen error -1");
        return -1; 
    }

    // 再读序列化数据
    ret = read(_fd, buf, jsonLen);
    if(-1 == ret && errno == EINTR){
        // errno == EINTR 表示错误类型为中断
        // 中断可以不进行异常处理
    }
    else if(-1 == ret){
        perror("readJson error -1");
        return -1; 
    }
    return 0;
}



int SocketIO::sendMsg(const pair<int, void*> msg){
    size_t ret; 
    json msgJson; 
    if(msg.first == 1){ // 关键字
        vector<string> result = *(static_cast<vector<string>*>(msg.second));  
        packMsgKey(result, msgJson); 
    }
    else{ // 网页
        vector<WebPage> result = *(static_cast<vector<WebPage>*>(msg.second));  
        packMsgWeb(result, msgJson); 
    }
    
    int msgLen = msgJson.dump().length();
    cout << "-------------------" << msgLen << endl; 
    // 发送消息长度 
    ret = send(_fd, &msgLen, sizeof(int), 0);  
    if(ret == -1 && errno == EINTR){} 
    else if(ret == -1){
        perror("Send msgLen");
        return -1;
    }   

    // 发送消息
    ret = send(_fd, msgJson.dump().c_str(), msgLen, 0); 
    if(ret == -1 && errno == EINTR){} 
    else if(ret == -1){
        perror("Send msgJson");
        return  -1;
    }
    return 0;
}



void SocketIO::packMsgKey(vector<string> msgKey, json &msgJson){
    string content;
    if(msgKey.size() == 0){
         msgJson = json{{"len", strlen("KeyWord Not Found!")}, 
                        {"type", 100},
                        {"content", "KeyWord Not Found!"}};
    }
    else{
        for(auto word:msgKey){
            cout << word << endl; 
            content += word;
            content += " ";
        }
        msgJson = json{{"len", content.length()}, 
                       {"type", 100},
                       {"content", content}};
    }
}



void SocketIO::packMsgWeb(const vector<WebPage> msgWeb, json &msgJson){
    if(msgWeb.size() == 0){
        msgJson = json{{"len", strlen("404 Not Found!")}, 
                       {"type", 200},
                       {"content", "404 Not Found!"}};
    }
    else{
        int count = 0;
        string count_s;
        msgJson = json{{"len", msgWeb.size()}, 
                       {"type", 200}};

        for(auto page:msgWeb){
            ++count; 
            count_s = std::to_string(count);
            string title = "title";   
            string link = "link";   
            string description = "description";   
            msgJson.emplace((title += count_s), page.title);
            msgJson.emplace((link += count_s), page.link);
            msgJson.emplace((description += count_s), page.description);
        }
        
        //for(auto &page:result){
        //   cout << page.title << endl;
        //   cout << page.link << endl;
        //   cout << page.description << endl;
        //   cout << page.content << endl;
        //} 
    }
}



